/* eslint-disable @typescript-eslint/no-use-before-define */
import React, { FC, useEffect, useState, useRef } from 'react';
import work from './work.js';
import { NavBar, SearchBar, List, Checkbox, Icon, Modal } from 'antd-mobile-v2';
import { List as VList, ListRowProps } from 'react-virtualized';
import AutoSizer from 'react-virtualized/dist/commonjs/AutoSizer';
import AntdRefreshList from '@/components/antd-refresh-list';
// import { Props, State } from '../type';
// import { WrapFormItem } from '../../common/form-item/formItem-decorate';
import styles from './index.module.less';

import { connect } from 'react-redux';
import { WrappedFormClass } from 'rc-form';
import { ConnectProps } from 'typings/connect';
import Avatar from '@/components/avatar';

import {
  IOrgTreeCheckedItem,
  IOrgTreeItem,
  IResOrgTreeItem
} from '@/plugins/form/form-components/contract-select/interface';
import {
  stopBodyScroll,
  recoverBodyScroll,
  getClientHeight,
  getClientWidth
} from '@/utils';

const CheckboxItem = Checkbox.CheckboxItem;
const Item = List.Item;

export interface IContractSelectModal extends ConnectProps {
  modalStatus: boolean;
  orgData: any;
  // recordId: string;
  form?: WrappedFormClass<{}>;
  closeModal: () => void;
  onRefreshStatus?: () => void;
  submit: (isHandle: boolean, selectArray: any[]) => void;
  saveOnSubmit: boolean; // 是否在触发 submit 事件时提交数据到后台
  type: 'dept' | 'person' | 'all';
  receiveData?: any; // 接收回填的数据（在已选数据基础上）
  resetData?: any; // 接收回填的数据（覆盖已选数据）
  mode?: 'single' | 'multiple';
  height?: number; // 虚拟列表高度
}

interface ISelectedItemObject {
  [index: string]: IOrgTreeItem | null;
}

// 审批业务首页
const ContractSelectModal: FC<IContractSelectModal> = (props) => {
  const [
    selectedItemObject,
    setSelectedItemObject
  ] = useState<ISelectedItemObject>({}); // 维护选中对象
  const [menuRouterData, setMenuRouterData] = useState<IOrgTreeItem[]>([]); // 存放联系人菜单完整数据
  const [routerActionStack, setRouterActionStack] = useState<number[]>([]); // 维护联系人路由栈堆
  const [routerShowText, setRouterShowText] = useState<any[]>(['通讯录']);
  const [searchStatus, setSearchStatus] = useState<boolean>(false);
  const [loading, setLoading] = useState<boolean>(false);
  const [matchSearchList, setMatchSearchList] = useState<any[]>([]);
  const [flattenObj, setFlattenObj] = useState<any>();
  const [searchValue, setSearchValue] = useState<string>('');
  const [searchSource, setSearchSource] = useState<any>(null);
  const [generateSearchList, setGenerateSearchList] = useState<
    { next: () => { value: any } } | undefined
  >();

  const [showSelectNum, setShowSelectNum] = useState<any>();
  const [pageList, setPageList] = useState<IOrgTreeItem[]>([]);
  const [upPageList, setUpPageList] = useState<IOrgTreeItem>(
    {} as IOrgTreeItem
  );
  const vlist = useRef();
  useEffect(() => {
    let newPageList = menuRouterData;
    let newUpPageList = { ...upPageList };
    if (routerActionStack.length > 0) {
      routerActionStack?.forEach((number: number, index: number) => {
        // console.log(newPageList, number);
        if (newPageList[number]?.children) {
          if (index === routerActionStack.length - 1) {
            // setUpPageList(newPageList[number]);
            newUpPageList = newPageList[number];
          } else {
            newUpPageList = menuRouterData[0];
          }
          newPageList = newPageList[number].children;
        } else {
          newPageList = [newPageList[number]];
        }
      });
      setUpPageList(newUpPageList);
      setPageList(newPageList);
    } else {
      menuRouterData?.length && setUpPageList(menuRouterData[0]);
      newPageList?.length && setPageList(newPageList);
    }
  }, [menuRouterData, routerActionStack]);

  useEffect(() => {
    const filterType =
      props.type === 'dept'
        ? 1
        : props.type === 'person'
          ? 2
          : props.type === 'all'
            ? 3
            : undefined;
    setShowSelectNum(
      Object.values(selectedItemObject)?.filter((item) => {
        if (
          filterType === 3 &&
          item &&
          (!item.children || !item.children.length) // 不要将部门的数据计算在显示的数量里
        ) {
          return true;
        } else {
          return item?.type == filterType && item?.key;
        }
      }).length
    );
  }, [selectedItemObject]);

  useEffect(() => {
    setLoading(true);
    if (typeof Worker !== 'undefined') {
      const worker = new Worker(work);
      worker.postMessage(props.orgData);
      worker.onmessage = function (event: any) {
        const orgData = event.data || {};
        setFlattenObj(orgData.flattenObj);
        setMenuRouterData(orgData.result);
        worker.terminate();
        setLoading(false);
      };
    } else {
      //抱歉! Web Worker 不支持
      requestData();
      setLoading(false);
    }
  }, [props.orgData]);

  useEffect(() => {
    const tempObj: ISelectedItemObject = {};
    if (!props.saveOnSubmit) {
      props.receiveData?.forEach(
        (item: {
          value: string;
          text: string;
          type: number;
          parentKey?: string;
        }) => {
          tempObj[item.value] = {
            ...item,
            title: item.text ? item.text : flattenObj?.[item.value]?.title,
            key: item.value,
            parentKey: item.parentKey
              ? item.parentKey
              : flattenObj?.[item.value]?.parentKey
          };
        }
      );
      if (
        JSON.stringify({ ...selectedItemObject, ...tempObj }) ===
        JSON.stringify(selectedItemObject)
      ) {
        // selectedItemObject 值不变时取消更新
        return;
      }

      // 修复单选的会和默认的值同时出现
      let dataObj = null;
      if (props.mode === 'single') {
        dataObj = tempObj;
      } else {
        dataObj = { ...selectedItemObject, ...tempObj };
      }
      setSelectedItemObject(dataObj);

      !props.saveOnSubmit && submitSelected(false, dataObj);
    }
  }, [props.receiveData, flattenObj]);

  useEffect(() => {
    const tempObj: ISelectedItemObject = {};
    props.resetData?.forEach(
      (item: { value: string; text: string; type: number }) =>
        (tempObj[item.value] = {
          ...item,
          title: item.text,
          key: item.value
        })
    );
    setSelectedItemObject({ ...tempObj });
    !props.saveOnSubmit && submitSelected(false, { ...tempObj });
  }, [props.resetData]);

  useEffect(() => {
    if (props.modalStatus) {
      console.log('stopBodyScroll');
      stopBodyScroll();
    } else {
      console.log('recoverBodyScroll');
      recoverBodyScroll();
    }
    return () => {
      console.log('recoverBodyScroll return');
      recoverBodyScroll();
    };
  }, [props.modalStatus]);

  const requestData = async () => {
    let { orgData } = props;
    if (!orgData) return;
    orgData = orgData instanceof Array ? orgData : [orgData];
    orgData = formatTreeData(orgData);
    setFlattenObj(orgData.flattenObj);
    setMenuRouterData(orgData.result);
  };

  const gotoDepartment = (
    event: { children?: any; title?: string },
    index: number
  ) => {
    if (!event?.children) {
      return;
    }
    if (props.type === 'dept' && event?.children.length === 0) {
      return;
    }
    if (event?.children) {
      setSearchSource(event?.children);
      if (vlist) {
        (vlist.current as any).scrollToRow(0);
      }
      // window.scrollTo(0, 0);
      setRouterActionStack([...routerActionStack, index]);
      setRouterShowText([...routerShowText, event?.title]);
    }
  };

  // 点击单选框
  const clickItemBox = (paramItem: IOrgTreeCheckedItem) => {
    if (!pageList?.length) return;
    const nextStatus = !selectedItemObject[paramItem.key]; //本次变更状态

    if (props?.mode === 'single') {
      if (selectedItemObject[paramItem.key]?.key === paramItem.key) {
        return setSelectedItemObject({});
      }
      return setSelectedItemObject({ [paramItem.key]: paramItem });
    }
    let result = deepFlattenData(paramItem, nextStatus, selectedItemObject);
    result = dealBottomUpDataStatus(paramItem, result);
    setSelectedItemObject({ ...result });
    // TODO
    // 异步加载数据之后选中列表视图不会更新，重新设置数组强制刷新视图 ，后面有时间找下原因;
    Promise.resolve().then(() => {
      setMatchSearchList([...matchSearchList]);
    });
  };

  const navToBack = () => {
    setSearchSource(null);
    if (searchStatus) {
      setSearchStatus(false);
      setSearchValue('');
      setGenerateSearchList(undefined);
      return;
    }
    if (routerActionStack.length) {
      const pos = routerActionStack[routerActionStack.length - 1];
      if (vlist && (pos || pos === 0)) {
        console.log('pos', pos);

        (vlist.current as any).scrollToRow(pos);
      }
      setRouterShowText(
        [...routerShowText].splice(0, routerShowText.length - 1)
      );
      setRouterActionStack(
        [...routerActionStack].splice(0, routerActionStack.length - 1)
      );
    } else {
      props.closeModal && props.closeModal();
    }
  };

  const submitSelected = (isHandle: boolean, object?: ISelectedItemObject) => {
    object = object || selectedItemObject;
    let selectedItemObjectArray = Object.values(object);
    if (props.type === 'all') {
      // 人和部门都可以选择时，如已选部门，不展示部门下人员
      selectedItemObjectArray = selectedItemObjectArray.filter((item: any) => {
        if (object[item?.parentKey]) return false;
        return item;
      });
    }
    selectedItemObjectArray = selectedItemObjectArray.map((item: any) => {
      return {
        ...item,
        parentName: flattenObj?.[item?.parentKey]?.title
      };
    });
    const filterType =
      props.type === 'dept'
        ? 1
        : props.type === 'person'
          ? 2
          : props.type === 'all'
            ? 3
            : undefined;
    const selectArray = selectedItemObjectArray.filter((item) => {
      if (filterType === 3) {
        return true;
      } else {
        return item?.type === filterType && item?.key;
      }
    });
    setSearchStatus(false);
    setSearchValue('');
    // console.log('已经选中数据', selectArray);
    setRouterShowText(['通讯录']);
    setRouterActionStack([]);
    setGenerateSearchList(undefined);
    props.submit && props.submit(isHandle, selectArray);
  };

  // 向下递归 遍历选中对象添加进维护的选中对象列表
  const deepFlattenData = (
    paramItem: IOrgTreeCheckedItem,
    nextStatus: boolean,
    selectedItem: { [x: string]: any }
  ) => {
    // const ObjectArray: any = Object.values(flattenObj);
    if (paramItem.type === 1) {
      // const childrenArray = ObjectArray.filter((item: { parentKey: string }) => item.parentKey === paramItem.key) || [];
      let childrenArray = [paramItem];
      if (paramItem.children) {
        childrenArray = paramItem.children;
      }
      if (paramItem.persons) {
        childrenArray = childrenArray.concat(paramItem.persons);
      }
      childrenArray.forEach((element: IOrgTreeCheckedItem) => {
        selectedItem[element.key] = nextStatus ? element : null;
        deepFlattenData(element, nextStatus, selectedItem);
      });
    }
    selectedItem[paramItem.key] = nextStatus ? flattenObj[paramItem.key] : null;
    return selectedItem;
  };

  // 向上递归修改上层item选中状态
  const dealBottomUpDataStatus = (
    paramItem: IOrgTreeCheckedItem,
    selectedItem: ISelectedItemObject
  ) => {
    // const {
    //   state: { flattenObj }
    // } = this;
    const { parentId, parentKey } = paramItem;
    const markParentId = parentId || parentKey || '';
    const ObjectArray: any = Object.values(flattenObj);
    let tempItemArray = Object.values(selectedItem).filter((item) => item);
    const fatherArray =
      ObjectArray.filter(
        (item: { parentKey: string }) => item.parentKey === markParentId
      ) || [];
    tempItemArray = tempItemArray.filter(
      (item) => item?.parentKey == markParentId
    );
    // console.log(tempItemArray, 'dealBottomUP');

    selectedItem[markParentId] =
      tempItemArray.length === fatherArray.length
        ? flattenObj[markParentId]
        : null;
    if (markParentId) {
      dealBottomUpDataStatus(flattenObj[markParentId], selectedItem);
    }

    return selectedItem;
  };

  const formatTreeData = (treeData: IResOrgTreeItem[], parentKey?: string) => {
    const result: IOrgTreeItem[] = [];
    let flattenObj: { [index: string]: IOrgTreeCheckedItem } = {};
    for (let i = 0; i < treeData?.length; i++) {
      let formattedPersons: IOrgTreeItem[] = [];
      let children: IOrgTreeItem[] = [];
      const personFlattenObj: { [index: string]: IOrgTreeCheckedItem } = {};
      let childFlattenObj: { [index: string]: IOrgTreeCheckedItem } = {};
      if (treeData[i]?.persons) {
        formattedPersons = treeData[i]?.persons?.map((el) => {
          const obj = {
            key: el.userId,
            title: el.name,
            type: el.type,
            parentKey: treeData[i].id
          };
          personFlattenObj[obj.key] = obj;
          return obj;
        });
      }
      if (treeData[i]?.children) {
        const tmp = formatTreeData(treeData[i].children || [], treeData[i].id);
        children = tmp.result;
        childFlattenObj = tmp.flattenObj;
        if (formattedPersons) {
          children = children
            ? children.concat(formattedPersons)
            : formattedPersons;

          childFlattenObj = { ...childFlattenObj, ...personFlattenObj };
        }
      }
      flattenObj = {
        [treeData[i].id]: {
          key: treeData[i].id,
          title: treeData[i].orgName,
          type: treeData[i].type,
          parentKey
        },
        ...flattenObj,
        ...childFlattenObj
      };
      result.push({
        key: treeData[i].id,
        title: treeData[i].orgName,
        type: treeData[i].type,
        children: children,
        parentId: parentKey
      });
    }
    return { result, flattenObj };
  };
  // 点击面包屑路由跳转
  const clickRouterTab = (index: number) => {
    setSearchSource(null);
    const res = routerShowText.slice(0, index + 1);
    const resRouterActionStack = routerActionStack.slice(0, index);
    setRouterShowText(res);
    setRouterActionStack(resRouterActionStack);
  };

  const handleSearch = (val: string) => {
    setSearchValue(val);
    if (!val) {
      setMatchSearchList([]);
      return;
    }
    let ObjectArray: any = Object.values(flattenObj || {});
    if (searchSource) {
      ObjectArray = searchSource;
    }

    const list = search(val, ObjectArray);
    const searchResult = list.next().value;
    setMatchSearchList(searchResult);
    setGenerateSearchList(list);
  };

  function* search(val: string, source: any, size = 20, offset = 0) {
    let searchResult = [];
    let dataOffset = offset; // 下拉的时候会加载更多，要偏移第一次搜索结果数据
    if (source) {
      for (const department of source) {
        const currentResult = searchByKeyword(val, department);
        if (currentResult) {
          searchResult.push(currentResult);
        }
        if (searchResult.length >= size + dataOffset) {
          yield searchResult.slice(dataOffset, size);
          dataOffset = 0;
          searchResult = [];
        }
      }
    }
    return searchResult;
  }

  function searchByKeyword(
    val: string,
    source: {
      title: string;
      parentKey?: string;
      key: string;
    }
  ) {
    if (source.title?.indexOf(val) > -1 || source?.key?.indexOf(val) > -1) {
      return {
        ...source,
        parentName: flattenObj?.[source?.parentKey]?.title
      };
    }
  }

  const handleLoadMore = () => {
    const list = generateSearchList?.next().value;
    if (list) {
      const searchResult = matchSearchList.concat(list);
      setMatchSearchList(searchResult);
      setGenerateSearchList(generateSearchList);
    }
  };

  const rowRenderer = ({ key, index, style }: ListRowProps) => {
    // 部门不展示人
    // console.log(key, index, style, pageList[index]);
    if (props?.type === 'dept' && pageList[index]?.type === 2) {
      return null;
    }
    // 判断是否需要显示箭头与可否进入下一页菜单
    let isShowArrow = false;
    if (
      props.type === 'dept' &&
      pageList[index]?.children &&
      pageList[index].children.some((item: any) => item.type === 1)
    ) {
      isShowArrow = true;
    }
    if (
      (props.type === 'person' || props.type === 'all') &&
      pageList[index]?.children &&
      pageList[index]?.children.length > 0
    ) {
      isShowArrow = true;
    }
    return (
      <Item
        key={key}
        style={style}
        className={styles.listItem}
        arrow={isShowArrow ? 'horizontal' : ''}
        multipleLine
        onClick={() => {
          if (pageList[index].children) {
            if (!isShowArrow) return;
            gotoDepartment(pageList[index], index);
          }
        }}
      >
        {pageList[index].children ? (
          props.mode === 'single' && props.type === 'person' ? (
            <Item
              key={pageList[index].key}
              // checked={selectedItemObject[pageList[index]?.key]}
              onClick={(e: any) => {
                e.stopPropagation();
                if (!isShowArrow) return;
                gotoDepartment(pageList[index], index);
              }}
            >
              {pageList[index].title}
            </Item>
          ) : (
            <CheckboxItem
              key={pageList[index].key}
              checked={selectedItemObject[pageList[index]?.key] ? true : false}
              onClick={(e: any) => {
                e.stopPropagation();
                clickItemBox(pageList[index]);
              }}
            >
              {pageList[index].title}
            </CheckboxItem>
          )
        ) : (
          <CheckboxItem
            key={pageList[index].key}
            checked={selectedItemObject[pageList[index]?.key] ? true : false}
            onClick={(e: any) => {
              // this.selectItem(e, pageList[index], index);
              e.stopPropagation();
              clickItemBox(pageList[index]);
            }}
          >
            <div className={styles.avatorArea}>
              <div className={styles.avatarWrap}>
                <Avatar name={pageList[index].title} />
              </div>
              <div className={styles.userInfoBox}>
                <h3>{pageList[index].title}</h3>
                <span>{pageList[index].title}</span>
              </div>
            </div>
          </CheckboxItem>
        )}
      </Item>
    );
  };

  return (
    <>
      {props.modalStatus && (
        <Modal
          className={styles.baseContainer}
          visible={props.modalStatus}
          popup
          // onClose={this.onClose}
          animationType='slide-up'
        >
          <div className={styles.navBarWrap}>
            <NavBar
              mode='light'
              icon={
                routerActionStack.length === 0 || searchStatus ? (
                  <span>取消</span>
                ) : (
                  <i className='icon iconfont'>&#xe721;</i>
                )
              }
              onLeftClick={navToBack}
            >
              {props.type === 'dept'
                ? '部门选择'
                : props.type === 'person'
                  ? '人员选择'
                  : '部门及人员选择'}
            </NavBar>
          </div>
          <div className={styles.searchWrap}>
            <SearchBar
              placeholder='搜索'
              value={searchValue}
              onFocus={() => {
                setSearchStatus(true);
              }}
              onCancel={() => {
                setSearchStatus(false);
                setSearchValue('');
                setMatchSearchList([]);
                setGenerateSearchList(undefined);
              }}
              onChange={(val) => {
                handleSearch(val);
              }}
            />
          </div>
          {!loading ? (
            !searchStatus ? (
              <>
                <div className={styles.breadcrumbsWrap}>
                  <div className={styles.breadcrumbs}>
                    {routerShowText?.map((item, index) => {
                      return (
                        <div className={styles.breadcrumbsItem} key={index}>
                          {index !== 0 && (
                            <Icon
                              style={{ flex: '0 0 auto' }}
                              type={'right'}
                              size={'xxs'}
                              color={'#d8d8d8'}
                            />
                          )}
                          <span
                            onClick={() => {
                              clickRouterTab(index);
                            }}
                            className={styles.routerAreaText}
                            style={
                              index + 1 < routerShowText.length
                                ? { color: '#D2022A' }
                                : { color: '#666666' }
                            }
                          >
                            {' '}
                            {item}
                          </span>
                        </div>
                      );
                    })}
                  </div>
                </div>
                {props.mode === 'multiple' ? (
                  <Item
                    className={styles.listItem}
                    multipleLine
                    style={{ marginBottom: 8 }}
                  >
                    <CheckboxItem
                      checked={
                        selectedItemObject[upPageList?.key] ? true : false
                      }
                      onClick={() => clickItemBox(upPageList)}
                    >
                      全选
                    </CheckboxItem>
                  </Item>
                ) : null}
                <AutoSizer disableHeight>
                  {({ width }) => (
                    <VList
                      width={width}
                      ref={vlist}
                      scrollToAlignment='center'
                      height={
                        props.height ||
                        getClientHeight() -
                          getClientWidth() *
                            (props.mode === 'multiple' ? 0.72 : 0.55)
                      } // 具体数值参考页面样式设计
                      rowHeight={56}
                      rowCount={pageList.length}
                      rowRenderer={rowRenderer}
                    />
                  )}
                </AutoSizer>
                {/* <VList
                        // ref="List"
                        // style={{ flex: 1, overflow: 'scroll' }}
                        width={'100vw'}
                        height={props.height || 350}
                        rowHeight={56}
                        // overscanRowCount={50}
                        rowCount={pageList.length}
                        rowRenderer={rowRenderer}
                      /> */}
              </>
            ) : (
              <>
                {matchSearchList?.length ? (
                  <AntdRefreshList
                    height={window.screen.height}
                    initialListSize={20}
                    dataSource={matchSearchList}
                    refreshing={false}
                    loadingMore={false}
                    showFooterText={false}
                    enableRefresh={false}
                    noMargin
                    renderRow={(item) => (
                      <Item
                        key={item.key}
                        className={styles.listItem}
                        multipleLine
                      >
                        {item.type === 1 ? (
                          <CheckboxItem
                            key={item.key}
                            checked={
                              selectedItemObject[item.key] ? true : false
                            }
                            onClick={(e: any) => {
                              e.stopPropagation();
                              clickItemBox(item);
                            }}
                          >
                            {item.title}
                          </CheckboxItem>
                        ) : (
                          <CheckboxItem
                            key={item.key}
                            checked={
                              selectedItemObject[item.key] ? true : false
                            }
                            onClick={(e: any) => {
                              // this.selectItem(e, item, index);
                              e.stopPropagation();
                              clickItemBox(item);
                            }}
                          >
                            <div className={styles.avatorArea}>
                              <div className={styles.avatarWrap}>
                                <Avatar name={item.title} />
                              </div>

                              <div className={styles.userInfoBox}>
                                <h3>{item.title}</h3>
                                <span>{item.parentName}</span>
                              </div>
                            </div>
                          </CheckboxItem>
                        )}
                      </Item>
                    )}
                    onEndReached={handleLoadMore}
                  />
                ) : searchValue ? (
                  <p className={styles.noSearch}>
                    没有找到“
                    <span style={{ color: '#D2022A' }}>{searchValue}</span>
                    ”相关结果
                  </p>
                ) : (
                  ''
                )}
              </>
            )
          ) : (
            <div className={styles.loading}>
              <i
                className={'iconfont iconjiazai mr-4 '}
                style={{ verticalAlign: 'middle' }}
              />
              {'正在加载'}
            </div>
          )}

          <div className={styles.ensureButtonWrap}>
            <span
              key='ensure'
              className={styles.ensureButton}
              onClick={() => {
                submitSelected(true);
              }}
            >
              确定{showSelectNum ? `(${showSelectNum})` : ''}
            </span>
          </div>
        </Modal>
      )}
    </>
  );
};

export default connect()(ContractSelectModal);

export { IOrgTreeCheckedItem, IOrgTreeItem, IResOrgTreeItem };
